package factorytest.iflytek.com.einkiflytekfactorytest.agingtest;

import android.content.Context;
import android.content.SharedPreferences;
import android.view.View;

import java.io.File;

import androidx.annotation.NonNull;
import factorytest.iflytek.com.einkiflytekfactorytest.R;
import factorytest.iflytek.com.einkiflytekfactorytest.common.FTUtils;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.TimeStringUtils;

public enum AgingTestItemAttr {

    sleep(2, "attr_sleep", R.string.aging_test_item_sleep, AgingTestConstants.SLEEP_MIN_COUNT, -1),
    reboot(4, "attr_reboot", R.string.aging_test_item_reboot, AgingTestConstants.REBOOT_MIN_COUNT, -1),
    hardware(3, "attr_hardware", R.string.aging_test_item_hardware, -1, AgingTestConstants.HARDWARE_TEST_TIME),
    emmc_cpu(1, "attr_emmc_cpu", R.string.aging_test_item_emmc_cpu, AgingTestConstants.EMMC_CPU_MIN_COUNT, -1),
    ;

    private final int id;
    private final String name;
    private final int nominalRes;
    private final int countOfTestOver;
    private final long timeOfTestOver;

    private AgingTestItemAttr(int id, String name, int nominalRes,
                              int countOfTestOver, long timeOfTestOver) {
        this.id = id;
        this.name = name;
        this.nominalRes = nominalRes;
        this.countOfTestOver = countOfTestOver;
        this.timeOfTestOver = timeOfTestOver;
    }


    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getNominalRes() {
        return nominalRes;
    }

    public String getNominalName(Context context) {
        return context.getString(getNominalRes());
    }

    private int getCountOfTestOver() {
        return countOfTestOver;
    }

    private long getTimeOfTestOver() {
        return timeOfTestOver;
    }

    public int getRealCountOfTestOver(Context context) {
        return (int) (getCountOfTestOver() * getRatioForTestOver(context));
    }

    public long getRealTimeOfTestOver(Context context) {
        return (long) (getTimeOfTestOver() * getRatioForTestOver(context));
    }

    public String getDetail(Context context) {

        if (getCountOfTestOver() > 0) {
            return getNominalName(context) + context.getString(R.string.aging_test_item_detail_count,
                    getRealCountOfTestOver(context));

        } else if (getTimeOfTestOver() > 0) {
            return getNominalName(context) + context.getString(R.string.aging_test_item_detail_time,
                    TimeStringUtils.makeTimeString((getRealTimeOfTestOver(context))));
        }

        return "";

    }

    public long getStartTime_ms(Context context) {

        return getLong(context, getName() + "_start_time" , 0);

    }

    public void setStartTime_ms(Context context, long ms) {

        setLong(context, getName() + "_start_time", ms);

    }

    public  long getExitTime_ms(Context context) {

        return getLong(context, getName() + "_exit_time", 0);

    }

    public  void setExitTime_ms(Context context, long ms) {

        setLong(context, getName() + "_exit_time", ms);

    }

    /**
     * 开始测试的绝对时间, 相对于格力时间
     */
    public long getStartTimeAbsolute_ms(Context context) {

        return getLong(context, getName() + "_start_time_absolute", System.currentTimeMillis());

    }

    public void setStartTimeAbsolute_ms(Context context, long ms) {

        setLong(context, getName() + "_start_time_absolute", ms);

    }

    public long getExitTimeAbsolute_ms(Context context) {

        return getLong(context, getName() + "_exit_time_absolute", System.currentTimeMillis());

    }

    public void setExitTimeAbsolute_ms(Context context, long ms) {

        setLong(context, getName() + "_exit_time_absolute", ms);

    }

    public  int getTestCount(Context context) {

        return getInt(context, getName() + "_test_count", 0);

    }

    public void setTestCount(Context context, int count) {

        setInt(context, getName() + "_test_count", count);

    }

    private float getRatioForTestOver(Context context) {

        return getFloat(context, getName() + "_ratio_test_over", 1.0f);

    }

    public  void setRatioForTestOver(Context context, float ratio) {

        setFloat(context, getName() + "_ratio_test_over", ratio);

    }

    private boolean isForceTestOver(Context context) {

        return getBoolean(context, getName() + "_force_test_over", false);

    }

    public  void setForceTestOver(Context context, boolean forceOver) {

        setBoolean(context, getName() + "_force_test_over", forceOver);

    }

    public boolean isTestOver(Context context) {
        if (isForceTestOver(context)) {
            return true;
        }

        if (getCountOfTestOver() > 0) {

            return getTestCount(context) >= getRealCountOfTestOver(context);

        } else if (getTimeOfTestOver() > 0) {

            if (getStartTime_ms(context) <= 0) {
                //小于0, 说明他重来没有设置过.即未 start 过
                return false;
            }

            return (getAgingTimeTick_ms(context) - getStartTime_ms(context)) >= getRealTimeOfTestOver(context);
        }

        return true;
    }

    public void clearAll(Context context) {

        setStartTime_ms(context, 0);
        setExitTime_ms(context, 0);

        setStartTimeAbsolute_ms(context, 0);
        setExitTimeAbsolute_ms(context, 0);

        setForceTestOver(context, false);
        setTestCount(context, 0);

        if (this == hardware) {
            clearHardwareAll(context);
        }

        if (this == reboot) {
            setRebootTestStarted(context, false);
        }
        if (this == emmc_cpu) {
            setEmmcCpuTestOK(context, true);
        }
    }

    public AgingTestItemBase getAgingTestItem(@NonNull Context context, @NonNull View view) {
        switch (this) {
            case sleep:
                return new TestSleep(context, view);
            case reboot:
                return new TestReboot(context, view);
            case hardware:
                return new TestHardware(context, view);
            case emmc_cpu:
                return new TestEmmcCpu(context, view);
        }

        return null;
    }



    //////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////

    /**
     * 不采用  System.currentTimeMillis(), 因为一旦设备掉电, 时间就全乱了
     * aging_time_tick 就是 aging 的 测试时间. 所以不需要他的start 和 exit
     */
    private final static String AGING_TIME_TICK = "aging_time_tick";

    public static long getAgingTimeTick_ms(Context context) {

        return getLong(context, AGING_TIME_TICK,    1);

    }

    public static void setAgingTimeTick_ms(Context context, long ms) {

        setLong(context, AGING_TIME_TICK, ms == 0 ? 1 : ms);

    }

    /**
     * 开始老化测试的绝对时间, 相对于格林时间
     */

    private final static String AGING_TIME_START_ABSOLUTE = "aging_time_start_absolute";

    public static long getAgingStartTimeAbsolute_ms(Context context) {

        return getLong(context, AGING_TIME_START_ABSOLUTE, System.currentTimeMillis());

    }

    public static void setAgingStartTimeAbsolute_ms(Context context, long ms) {

        setLong(context, AGING_TIME_START_ABSOLUTE, ms);

    }

    private final static String AGING_TIME_EXIT_ABSOLUTE = "aging_time_exit_absolute";

    public static long getAgingExitTimeAbsolute_ms(Context context) {

        return getLong(context, AGING_TIME_EXIT_ABSOLUTE, System.currentTimeMillis());

    }

    public static void setAgingExitTimeAbsolute_ms(Context context, long ms) {

        setLong(context, AGING_TIME_EXIT_ABSOLUTE, ms);

    }

    //老化可以手动退出, 那么在退出时, 是否保留测试记录, 以便下次接着测试.
    // 在相对时间里, 这个 flag 作用不是那么大.
    private final static String AGING_KEEP_RECORD = "aging_keep_record_boolean";

    public static boolean isAgingKeepRecord(Context context) {

        return getBoolean(context, AGING_KEEP_RECORD, false);
    }

    public static void setAgingKeepRecord(Context context, boolean keep) {

        setBoolean(context, AGING_KEEP_RECORD, keep);

    }

    //是否是按测试要求主动退出ok.
    private final static String AGING_EXIT_OK = "aging_exit_ok_boolean";

    public static boolean isAgingExitOk(Context context) {

        return getBoolean(context, AGING_EXIT_OK, false);
    }

    public static void setAgingExitOk(Context context, boolean ok) {

        setBoolean(context, AGING_EXIT_OK, ok);

    }

    /**
     * 老化状态: true 表示 还在进行老化测试, false 表示 老化测试已经结束.
     */
    private final static String AGING_STATE = "aging_state_boolean";

    public static boolean isAgingTestEnabled(Context context) {

        return getBoolean(context, AGING_STATE, false);

    }

    public static void setAgingTestEnabled(Context context, boolean enabled) {

        setBoolean(context, AGING_STATE, enabled );

    }

    public static void clearAgingAll(Context context) {

        setAgingExitOk(context, false);
        setAgingExitTimeAbsolute_ms(context, 0);
        setAgingKeepRecord(context, false);

        setAgingStartTimeAbsolute_ms(context, 0);
        setAgingTestEnabled(context, false);
        setAgingTimeTick_ms(context, 0);

    }


    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    //for hardware test

    private final static String HARDWARE_SCREEN_COUNT = "hardware_screen_count";
    public static int getHardwareScreenCount(Context context) {

        return getInt(context, HARDWARE_SCREEN_COUNT, 0);

    }

    public static void setHardwareScreenCount(Context context, int count) {

        setInt(context, HARDWARE_SCREEN_COUNT, count);

    }

    private final static String HARDWARE_WIFI_ONOFF_COUNT = "hardware_wifi_onoff_count";
    public static int getHardwareWifiOnOffCount(Context context) {

        return getInt(context, HARDWARE_WIFI_ONOFF_COUNT, 0);

    }

    public static void setHardwareWifiOnOffCount(Context context, int count) {

        setInt(context, HARDWARE_WIFI_ONOFF_COUNT, count);

    }

    private final static String HARDWARE_BT_ONOFF_COUNT = "hardware_bt_onoff_count";
    public static int getHardwareBTOnOffCount(Context context) {

        return getInt(context, HARDWARE_BT_ONOFF_COUNT, 0);

    }

    public static void setHardwareBTOnOffCount(Context context, int count) {

        setInt(context, HARDWARE_BT_ONOFF_COUNT, count);

    }

    private final static String HARDWARE_PLAY_SOUND_COUNT = "hardware_play_sound_count";
    public static int getHardwarePlaySoundCount(Context context) {

        return getInt(context, HARDWARE_PLAY_SOUND_COUNT, 0);

    }

    public static void setHardwarePlaySoundCount(Context context, int count) {

        setInt(context, HARDWARE_PLAY_SOUND_COUNT, count);

    }

    private final static String HARDWARE_RECORD_COUNT = "hardware_record_count";
    public static int getHardwareRecordCount(Context context) {

        return getInt(context, HARDWARE_RECORD_COUNT, 0);

    }

    public static void setHardwareRecordCount(Context context, int count) {

        setInt(context, HARDWARE_RECORD_COUNT, count);

    }

    private final static String HARDWARE_LED_COUNT = "hardware_led_count";
    public static int getHardwareLedCount(Context context) {

        return getInt(context, HARDWARE_LED_COUNT, 0);

    }

    public static void setHardwareLedCount(Context context, int count) {

        setInt(context, HARDWARE_LED_COUNT, count);

    }


    private final static String HARDWARE_EMMC_COUNT = "hardware_emmc_count";
    public static int getHardwareEmmcCount(Context context) {

        return getInt(context, HARDWARE_EMMC_COUNT, 0);

    }

    public static void setHardwareEmmcCount(Context context, int count) {

        setInt(context, HARDWARE_EMMC_COUNT, count);

    }

    public final static String PATH_TEST_EMMC_FAIL = FTUtils.getFTStorageDirectory() + File.separator + "emmcFail.log";
    public final static String PATH_TEST_EMMC_HARDWARE_FAIL = FTUtils.getFTStorageDirectory() + File.separator + "hardwareEmmcFail.log";
    private final static String HARDWARE_EMMC_TEST_FAILED = "hardware_emmc_test_failed_boolean";
    public static boolean isHardwareEmmcTestFailed(Context context) {

        return getBoolean(context, HARDWARE_EMMC_TEST_FAILED, false);

    }

    public static void setHardwareEmmcTestFailed(Context context, boolean failed) {

        setBoolean(context, HARDWARE_EMMC_TEST_FAILED, failed);

    }

    private final static String HARDWARE_CPU_TEST_COUNT = "hardware_cpu_test_count";
    public static int getHardwareCpuTestCount(Context context) {

        return getInt(context, HARDWARE_CPU_TEST_COUNT, 0);

    }

    public static void setHardwareCpuTestCount(Context context, int count) {

        setInt(context, HARDWARE_CPU_TEST_COUNT, count);

    }

    private final static String HARDWARE_CPU_FAIL_COUNT = "hardware_cpu_fail_count";
    public static int getHardwareCpuFailCount(Context context) {

        return getInt(context, HARDWARE_CPU_FAIL_COUNT, 0);

    }

    public static void setHardwareCpuFailCount(Context context, int count) {

        setInt(context, HARDWARE_CPU_FAIL_COUNT, count);

    }

    public static void clearHardwareAll(Context context) {

        setHardwareBTOnOffCount(context, 0);
        setHardwareCpuFailCount(context, 0);
        setHardwareCpuTestCount(context, 0);
        setHardwareEmmcCount(context, 0);
        setHardwareEmmcTestFailed(context, false);

        setHardwareLedCount(context, 0);
        setHardwarePlaySoundCount(context, 0);
        setHardwareRecordCount(context, 0);
        setHardwareScreenCount(context, 0);
        setHardwareWifiOnOffCount(context, 0);

    }

    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    //for reboot test
    /**
     * 针对重启需要做一些特殊处理
     */
    private final static String REBOOT_TEST_STARTED = "reboot_test_started_boolean";

    public static boolean isRebootTestStarted(Context context) {

        return getBoolean(context, REBOOT_TEST_STARTED, false);

    }

    public static void setRebootTestStarted(Context context, boolean started) {

        setBoolean(context, REBOOT_TEST_STARTED, started );

    }

    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    //for test emmc and cpu
    /**
     * 针对单独测试 emmc, cpu 需要做一些特殊处理
     */
    private final static String EMMC_CPU_TEST_IS_OK = "emmc_cpu_test_is_ok_boolean";

    public static boolean isEmmcCpuTestOK(Context context) {

        return getBoolean(context, EMMC_CPU_TEST_IS_OK, true);

    }

    public static void setEmmcCpuTestOK(Context context, boolean ok) {

        setBoolean(context, EMMC_CPU_TEST_IS_OK, ok );

    }

    private final static String EMMC_CPU_TEST_FAILED_LOG = "emmc_cpu_test_failed_log_string";

    public static void setLogForEmmcCpuTestFailed(Context context, String log) {

        setString(context, EMMC_CPU_TEST_FAILED_LOG, log);

    }
    public static String getLogForEmmcCpuTestFailed(Context context) {

        return getString(context, EMMC_CPU_TEST_FAILED_LOG, "");

    }

    ////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 测试 eink 用到的 sharedPreferences name;
     */
    private final static String EINK_SHARED_PREF_NAME = "eink_aging_shared_preferences";

    private static boolean getBoolean(Context context, String name, boolean defValue) {
        if (context == null) {
            return false;
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);

        return sp.getBoolean(name, defValue);
    }

    private static void setBoolean(Context context, String name, boolean value) {
        if (context == null) {
            return;
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);

        SharedPreferences.Editor editor = sp.edit();

        editor.putBoolean(name, value);

        editor.apply();
    }

    private static int getInt(Context context, String name, int defValue) {
        if (context == null) {
            return 0;
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);

        return sp.getInt(name, defValue);
    }

    private static void setInt(Context context, String name, int value) {
        if (context == null) {
            return;
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);

        SharedPreferences.Editor editor = sp.edit();

        editor.putInt(name, value);

        editor.apply();
    }

    private static long getLong(Context context, String name, long defValue) {
        if (context == null) {
            return -1;
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);
        return sp.getLong(name, defValue);
    }

    private static void setLong(Context context, String name, long value) {
        if (context == null) {
            return;
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putLong(name, value);
        editor.apply();
    }

    private static float getFloat(Context context, String name, float defValue) {
        if (context == null) {
            return -1;
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);
        return sp.getFloat(name, defValue);
    }

    private static void setFloat(Context context, String name, float value) {
        if (context == null) {
            return;
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putFloat(name, value);
        editor.apply();
    }

    private static String getString(Context context, String name, String defValue) {
        if (context == null) {
            return "";
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);
        return sp.getString(name, defValue);
    }

    private static void setString(Context context, String name, String value) {
        if (context == null) {
            return;
        }

        SharedPreferences sp = context.getSharedPreferences(EINK_SHARED_PREF_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(name, value);
        editor.apply();
    }


}
